package com.bwie.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.config.KafkaConfig;
import com.bwie.config.MyNacosConfig;
import com.bwie.mapper.TbLogMapper;
import com.bwie.pojo.TbLog;
import com.bwie.pojo.TbUser;
import com.bwie.pojo.TbUserRole;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginVo;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author andy
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-03-21 14:01:00
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    MyNacosConfig myNacosConfig;

    @Autowired
    FastFileStorageClient fastFileStorageClient;

    @Autowired
    HttpServletRequest request;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Autowired
    TbLogMapper tbLogMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R getUserById(Integer userId) {

        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null) {
            return R.ERROR(404, "用户不存在");
        }

        return R.OK(tbUser);
    }

    @Override
    public R login(LoginVo loginVo) {
        //-- 判断用户是否存在
        TbUser tbUser = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, loginVo.getUserName())
        );
        if(tbUser == null) {
            return R.ERROR(404, "用户不存在");
        }

        //-- 密码是否正确
        if(!tbUser.getUserPass().equals(loginVo.getUserPass())) {
            return R.ERROR(500, "密码错误");
        }

        //-- 生成token
        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", tbUser.getUserId())
                .claim("userName", tbUser.getUserName())
                .claim("realName", tbUser.getRealName())
                .compact();

        //-- 缓存token
        String tokenKey = "token-" + tbUser.getUserId();
        stringRedisTemplate.opsForValue().set(tokenKey, token, 60, TimeUnit.MINUTES);


        //-- 返回用户信息
        tbUser.setUserPass(null);
        tbUser.setToken(token);

        return R.OK(tbUser);
    }

    @Override
    public R getUserList(PageInfoVo pageInfoVo) {

        String token = request.getHeader("token");
        if(token == null) {
            return R.ERROR(500, "请先登录");
        }
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId", Integer.class);

        // 判断当前用户是否为管理员
        List<TbUserRole> roleList = tbUserMapper.getUserRoleList(userId);
        Boolean isAdmin = false;
        for (TbUserRole tbUserRole : roleList) {
            if(tbUserRole.getRoleName().equals("管理员")) {
                isAdmin = true;
                break;
            }
        }

        //-- 定义分页参数
        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        //-- 获取分页数据
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        if(!isAdmin) {
            // 不是管理员，则只查自己
            wrapper.lambda().eq(TbUser::getUserId, userId);
        }

        // 添加搜索条件
        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())) {
            wrapper.lambda()
                    .like(TbUser::getUserName, pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getRealName, pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getUserMobile, pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getUserEmail, pageInfoVo.getKeyWord());
        }

        wrapper.lambda().orderByDesc(TbUser::getUserId);


        Page<TbUser> tbUserPage = tbUserMapper.selectPage(page, wrapper);

        //-- 返回分页数据
        return R.OK(tbUserPage);
    }

    @Override
    public R addUser(TbUser tbUser) {
        //--1 验证用户名是否重复
        TbUser user = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, tbUser.getUserName())
        );
        if(user != null) {
            return R.ERROR(500, "用户名重复");
        }

        //--2 保存用户信息
        tbUserMapper.insert(tbUser);

        return R.OK();
    }

    @Override
    public R getConfigFromNacos() {
        String className = myNacosConfig.getClassName();
        System.out.println("className=" + className);
        return R.OK(className);
    }

    @Override
    public R uploadImage(MultipartFile file) {

        try {
            String extName = FileNameUtil.extName(file.getOriginalFilename());
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
            if(storePath == null) {
                return R.ERROR(500, "上传失败");
            }
            String url = "http://192.168.80.192:8888/" + storePath.getFullPath();
            return R.OK(url);
        } catch (IOException e) {
            //throw new RuntimeException(e);
            e.printStackTrace();
            return R.ERROR(500, "上传失败");
        }
    }

    @Override
    public R getUserRole(Integer userId) {

        List<TbUserRole> roleList = tbUserMapper.getUserRoleList(userId);

        return R.OK(roleList);
    }

    @Override
    public R checkUser(TbUser tbUser) {
        //-- 如果驳回，必须输入驳回原因
        if(tbUser.getCheckStatus() == 2) {
            if(StringUtils.isEmpty(tbUser.getCheckReason())) {
                return R.ERROR(500, "驳回原因不能为空");
            }
        }

        //-- 更新用户状态
        tbUserMapper.updateById(tbUser);

        //-- 发送短信+记录日志
        if(tbUser.getCheckStatus() == 2) {
            // 发送kafka消息
            String message = JSON.toJSONString(tbUser);
            System.out.println("发送kafka消息：" + message);
            kafkaTemplate.send(KafkaConfig.TOPIC_LOG, message);
        }

        // 批量添加


        return R.OK();
    }

    @Override
    public R updateUser(TbUser tbUser) {
        //--1 验证用户名是否存在
        TbUser user = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, tbUser.getUserName())
        );
        if(user == null) {
            return R.ERROR(404, "用户不存在");
        }

        //--2 保存用户信息
        tbUserMapper.updateById(tbUser);

        return R.OK();
    }

    @Override
    public R deleteUserById(Integer userId) {

        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null) {
            return R.ERROR(404, "用户不存在");
        }

        tbUserMapper.deleteById(userId);

        return R.OK();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteUserAll(List<TbUser> userList) {

        for (TbUser tbUser : userList) {
            tbUserMapper.deleteById(tbUser.getUserId());
        }

        return R.OK();
    }

    @KafkaListener(topics = KafkaConfig.TOPIC_LOG)
    public void recvLogMessage(String message, Acknowledgment acknowledgment) {
        System.out.println("接收到消息："+message);

        //
        TbUser tbUser = JSON.parseObject(message, TbUser.class);

        // 发送短信
        String mobile = tbUser.getUserMobile();
        String content = "您的账号：" + tbUser.getUserName() + "，审核结果：已通过";
        if(tbUser.getCheckStatus() == 2) {
            content = "您的账号：" + tbUser.getUserName() + "，审核结果：已驳回,原因:" + tbUser.getCheckReason();
        }
        MobileMessageUtil.sendMobileMessage(mobile, content);


        // 记录日志
        TbLog tbLog = new TbLog();
        tbLog.setLogContent(content);
        tbLog.setLogTime(new Date());
        tbLogMapper.insert(tbLog);

        // 手动确认消息
        acknowledgment.acknowledge();
        System.out.println("消息已确认");
    }

}




